package org.yagnus.scalasupport
import scala.collection.mutable.ListBuffer
import scala.collection.mutable.WeakHashMap

/**
 * This class copies App.scala in preparing a function that is all of the init code
 *
 * The method applyDelayedInits can be invoked by deriving class when ready.
 *
 */
trait DelayedInitImpl[ContextData] extends DelayedInit {

  private val initCode = new ListBuffer[() => Unit]

  override def delayedInit(body: => Unit) {
    initCode += (() => body)
  }

  protected def applyDelayedInits(cd: ContextData) {
    setContext(cd);
    applyDelayedInits;
  }
  private def applyDelayedInits {
    initCode.map(_());
  }
  protected def setContext(d: ContextData) { DelayedInitImplCache.cache.update(this, d); }
  protected def getContext: ContextData = DelayedInitImplCache.cache.getOrElse(this, null).asInstanceOf[ContextData];
}

object DelayedInitImplCache {
  val cache: WeakHashMap[AnyRef, Any] = new WeakHashMap[AnyRef, Any]();
}

object Ahhaaa_this_is_soooo_cool extends App {
  class A extends DelayedInitImpl[{ val a: Int; val b: String }] {
    lazy val data = getContext.a;
    val msg = getContext.b;
    val d2 = data + 1;
    val d3 = d2 + 2;
    def conf(i: Int) {
      applyDelayedInits(new { val a = 1; val b = "hello world."; });
    }
  }

  val t = new A();
  t.conf(100);
  println("the d3 is " + t.d3 + " and the message is '" + t.msg + "'");

}